package com.tian.config;

import com.tian.constant.RabbitMQConstant;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

/**
 * {@code @description:} rabbitMQ
 *
 * @author tianwc 公众号：Java后端技术全栈
 * 在线刷题 1200+java面试题和1000+篇技术文章：<a href="https://woaijava.cc/">博客地址</a>
 * {@code @date:} 2024-03-24 9:17
 * {@code @version:} 1.0
 */
@Configuration
public class RabbitConfig {
    @Bean
    public Queue queueUserUseCoupon() {
        return new Queue(RabbitMQConstant.USER_USE_COUPON_QUEUE, true);
    }

    @Bean
    TopicExchange exchangeUserUseCoupon() {
        return new TopicExchange(RabbitMQConstant.USER_USE_COUPON_EXCHANGE, true, false);
    }

    @Bean
    Binding bindingUserUsingCoupon(Queue queueUserUseCoupon, TopicExchange exchangeUserUseCoupon) {
        return BindingBuilder.bind(queueUserUseCoupon).to(exchangeUserUseCoupon).with(RabbitMQConstant.USER_USE_COUPON_ROUTING_KEY);
    }
    @Bean
    public Queue queueUserUsedBalanceIncrease() {
        return new Queue(RabbitMQConstant.USER_BALANCE_INCREASE_QUEUE, true);
    }

    @Bean
    TopicExchange exchangeUsedBalanceIncrease() {
        return new TopicExchange(RabbitMQConstant.USER_BALANCE_INCREASE_EXCHANGE, true, false);
    }

    @Bean
    Binding bindingUsedBalanceIncrease(Queue queueUserUsedBalanceIncrease, TopicExchange exchangeUsedBalanceIncrease) {
        return BindingBuilder.bind(queueUserUsedBalanceIncrease).to(exchangeUsedBalanceIncrease).with(RabbitMQConstant.USER_BALANCE_INCREASE_ROUTING_KEY);
    }

    @Bean
    public Queue queueChargingOrder() {
        return new Queue(RabbitMQConstant.CHARGING_ORDER_STATUS_CHANGE_QUEUE, true);
    }

    @Bean
    TopicExchange exchangeChargingOrder() {
        return new TopicExchange(RabbitMQConstant.CHARGING_ORDER_STATUS_CHANGE_EXCHANGE, true, false);
    }

    @Bean
    Binding bindingChargingOrder(Queue queueChargingOrder, TopicExchange exchangeChargingOrder) {
        return BindingBuilder.bind(queueChargingOrder).to(exchangeChargingOrder).with(RabbitMQConstant.CHARGING_ORDER_STATUS_CHANGE_ROUTING_KEY);
    }


    @Bean
    public Queue queueCouponUseStatistics() {
        return new Queue(RabbitMQConstant.COUPON_USE_STATISTICS_QUEUE, true);
    }

    @Bean
    TopicExchange exchangeCouponUseStatistics() {
        return new TopicExchange(RabbitMQConstant.COUPON_USE_STATISTICS_EXCHANGE, true, false);
    }

    @Bean
    Binding bindingCouponUseStatistics(Queue queueCouponUseStatistics, TopicExchange exchangeCouponUseStatistics) {
        return BindingBuilder.bind(queueCouponUseStatistics).to(exchangeCouponUseStatistics).with(RabbitMQConstant.COUPON_USE_STATISTICS_ROUTING_KEY);
    }

    @Bean
    public Queue queueUserUseCouponExchangeCode() {
        return new Queue(RabbitMQConstant.USER_USE_COUPON_EXCHANGE_CODE_QUEUE, true);
    }

    @Bean
    TopicExchange exchangeUserUseCouponExchangeCode() {
        return new TopicExchange(RabbitMQConstant.USER_USE_COUPON_EXCHANGE_CODE_EXCHANGE, true, false);
    }

    @Bean
    Binding bindingUserUseCouponExchangeCode(Queue queueUserUseCouponExchangeCode, TopicExchange exchangeUserUseCouponExchangeCode) {
        return BindingBuilder.bind(queueUserUseCouponExchangeCode).to(exchangeUserUseCouponExchangeCode).with(RabbitMQConstant.USER_USE_COUPON_EXCHANGE_CODE_ROUTING_KEY);
    }

    //用户积分添加
    @Bean
    public Queue queueUserChangePointAdd() {
        return new Queue(RabbitMQConstant.USER_POINT_ADD_QUEUE, true);
    }

    @Bean
    TopicExchange exchangeUserChangePointAdd() {
        return new TopicExchange(RabbitMQConstant.USER_POINT_ADD_EXCHANGE, true, false);
    }

    @Bean
    Binding bindingUserChangePointAdd(Queue queueUserChangePointAdd, TopicExchange exchangeUserChangePointAdd) {
        return BindingBuilder.bind(queueUserChangePointAdd).to(exchangeUserChangePointAdd).with(RabbitMQConstant.USER_POINT_ADD_ROUTING_KEY);
    }

    @Bean
    @Scope("prototype")
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate();
        rabbitTemplate.setConnectionFactory(connectionFactory);
        //设置消息投递失败的策略，有两种策略：自动删除或返回到客户端。
        //我们既然要做可靠性，当然是设置为返回到客户端(true是返回客户端，false是自动删除)
        rabbitTemplate.setMandatory(true);
        return rabbitTemplate;
    }

    @Bean
    public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
        factory.setConnectionFactory(connectionFactory);
        factory.setMessageConverter(new Jackson2JsonMessageConverter());
        return factory;
    }
}
